from django.shortcuts import render, redirect
from app01 import models
from django import forms
# 验证方式1：引入对模型的正则表达式
from django.core.validators import RegexValidator
# 验证方式2
from django.core.exceptions import ValidationError
# 后端代码安全标记到前端
from django.utils.safestring import mark_safe
# 分页组件类
from app01.utils.pagination import Pagination

from app01.utils.bootstrap import BootStrapModelForm, BootStrapForm

# 密码加密
from app01.utils.encrypt import md5


class UserModelForm(BootStrapModelForm):
    # 字段重构:编写验证规则
    name = forms.CharField(
        min_length=3,
        label="姓名",
        widget=forms.TextInput(attrs={"class": "form-control"})
    )
    password = forms.CharField(min_length=6, label="密码")  # validators:正则表达式，密码是6-18位数字

    class Meta:
        model = models.UserInfo
        fields = ["name", "password", "age", "account", "create_time", "gender", "depart"]


class PrettyModelForm(BootStrapModelForm):
    # 使用bootstrap样式
    # 获取模板元包
    class Meta:
        model = models.PrettyNum
        # 获取字段
        # fields = "__all__"#获取全部字段
        # exclude = ["level"]#反选指定字段
        fields = ["mobile", "price", "level", "status"]  # 获取指定字段

    # 验证方式2：钩子函数
    def clean_mobile(self):
        txt_mobile = self.cleaned_data["mobile"]
        # 验证手机号是否已存在
        exists = models.PrettyNum.objects.filter(mobile=txt_mobile).exists()
        if exists:
            raise ValidationError("手机号已存在")
        elif len(txt_mobile) != 11:
            raise ValidationError("手机号格式错误")
        return txt_mobile


class PrettyEditModelForm(BootStrapModelForm):
    mobile = forms.CharField(disabled=True, label="手机号")
    # 验证方式1：正则表达式
    mobile = forms.CharField(
        label="手机号",
        validators=[RegexValidator(r'[3-9]\d{9}$', '手机号格式错误')],  # \d{11}#1[3-9]\d{9}$
    )

    class Meta:
        model = models.PrettyNum
        fields = ["mobile", "price", "level", "status"]

    def clean_mobile(self):
        # 当前编辑的那一行主键（id）
        # print(self.instance.pk)
        txt_mobile = self.cleaned_data["mobile"]
        # 验证手机号是否已存在(排除自身)
        exists = models.PrettyNum.objects.exclude(id=self.instance.pk).filter(mobile=txt_mobile).exists()
        if exists:
            raise ValidationError("手机号已存在")
        elif len(txt_mobile) != 11:
            raise ValidationError("手机号格式错误")
        return txt_mobile


class AdminModelForm(BootStrapModelForm):
    # 自定义字段，不改变数据库
    confirm_password = forms.CharField(
        label="确认密码",
        widget=forms.PasswordInput  # (render_value=True)加此参数，密码不会清空
    )

    class Meta:
        model = models.Admin
        fields = ["username", "password", "confirm_password"]

        widgets = {
            "password": forms.PasswordInput  # (render_value=True)加此参数，密码不会清空
        }

    def clean_password(self):
        """原密码加密"""
        pwd = self.cleaned_data.get("password")
        # 返回密文
        return md5(pwd)

    def clean_confirm_password(self):
        # 对第二次的密码进行md5加密
        pwd = self.cleaned_data.get("password")
        confirm = md5(self.cleaned_data.get("confirm_password"))
        if confirm != pwd:
            raise ValidationError("两次输入密码不一致")
        return confirm


class AdminEditModelForm(BootStrapModelForm):
    class Meta:
        model = models.Admin
        fields = ['username']


class AdminResetPasswordModelForm(BootStrapModelForm):
    confirm_password = forms.CharField(
        label="确认密码",
        widget=forms.PasswordInput  # (render_value=True)加此参数，密码不会清空
    )

    class Meta:
        model = models.Admin
        fields = ['password', 'confirm_password']
        widgets = {
            "password": forms.PasswordInput(render_value=True)
        }

    def clean_password(self):
        """原密码加密"""
        pwd = self.cleaned_data.get("password")
        md5_pwd = md5(pwd)
        # 去数据库比对，是否当前的密码和原来的一致
        exists = models.Admin.objects.filter(id=self.instance.pk, password=md5_pwd).exists()  # pk就是id
        if exists:
            raise ValidationError("密码不能与之前的一致！")
        return md5_pwd

    def clean_confirm_password(self):
        # 对第二次的密码进行md5加密
        pwd = self.cleaned_data.get("password")
        confirm = md5(self.cleaned_data.get("confirm_password"))
        if confirm != pwd:
            raise ValidationError("两次输入密码不一致")
        return confirm


class LoginForm(BootStrapForm):  # 采用继承
    username = forms.CharField(
        label="用户名",
        widget=forms.TextInput,  # (attrs={'class':"form-control",'placeholder':'用户名'})
        required=True  # 必填项
    )
    password = forms.CharField(
        label="密码",
        widget=forms.PasswordInput(render_value=True),
        # render_value=True:保留原来字段#(attrs={'class':"form-control",'placeholder':'密码'})
        required=True  # 必填项
    )
    code = forms.CharField(
        label="用户名",
        widget=forms.TextInput,
        required=True  # 必填项
    )

    def clean_password(self):
        pwd = self.cleaned_data.get("password")
        return md5(pwd)


# class LoginModelForm(forms.ModelForm):
#     class Meta:
#         model = models.Admin
#         fields = ["username",'password']

class TaskModelForm(BootStrapModelForm):
    class Meta:
        model = models.Task
        fields = "__all__"
        widgets = {
            "detail": forms.TextInput,
            # "detail": forms.Textarea,
        }


class OrderModelForm(BootStrapModelForm):
    class Meta:
        model = models.Order
        # fields = '__all__'
        exclude = ["oid", "admin"]


class UpForm(BootStrapForm):
    # 将img加入bootstrap_exclude_fields列表可以排除它的样式
    bootstrap_exclude_fields = ['img']

    name = forms.CharField(label="姓名")
    age = forms.IntegerField(label="年龄")
    img = forms.FileField(label="头像")


class UpModelForm(BootStrapModelForm):
    bootstrap_exclude_fields = ['img']

    class Meta:
        model = models.City
        bootstrap_exclude_fields = ['img']
        fields = "__all__"
